
/*
 * AssemblerApplication1.asm
 *
 *  Created: 2/13/2014 3:57:34 PM
 *   Author: hillm3
 */ 

 // R27,R26 = X
 // R29,R28 = Y
 // R31,R30 = Z
 



.MACRO ReduceByX ; Defines the MACRO ReduceByX
;; This macro reduces the number below a certain point. Eg. if reduce by 30 and the number is 70, it will output a 10 in R17
CP R17, R18 ; Check if value is already under N
BRLO LessThanN ; If value is already under N, then no need to subtract
MinusN: ; Value must be equal or over N
SUB R17, R18 ; Reduce value by N
CP R17, R18 ; Check if value is less than N
BRSH MinusN ; If it is still greater than loop back up
LessThanN: ; If it is less than, finish.

.ENDMACRO

.MACRO BreakPoint
NOP
.ENDMACRO



//////////////////////////////////////  Initialize Variables
;;; Initialize the stack
LDI R16,HIGH(RAMEND) ;; Get high of end of ram
OUT SPH,R16 ;; Set SPH to high of end of ram
LDI R16,LOW(RAMEND) ;; Get low of end of ram
OUT SPL,R16 ;; Set SPL to low of end of ram





/// Method of a random gen:
/// start number: 50
/// add +75 each loop.
/// if number less than or equal to 30, add 44. If number greater than or equal to 230, minus 27
/// Numbers: 50,125,200,69,


LDI R16, 20 ; State how many numbers want to be interated
ldi R17, 50 ; This is the psuedo random number start
ldi R18, 31 ; Holds 30 for compare
ldi R19, 44 ; Holds 44 to add
ldi R20, 230; Holds 230 to compare
ldi R21, 87; Holds 27 to subtract
LDI R22, 75; Holds 75 to add per iteration

//////////////////////////////////////  END Initialize Variables
















//////////////////////////////////////  Generate List



PushList: ;; PushList Label
PUSH R17  ; Store each number on the RAM



;;; Make the next X.
ADD R17, R22; Add 75 onto R17.

CP R17, R18 ; Check if(R17<30)
BRSH NotLower ; If greater than 30, skip this.
ADD R17, R19 ; Less than 30, so have to increase the register
NotLower: ;; Label

CP R17, R20 ; Check if (R17>230)
BRLO NotGreater ; If R17>230
SUB R17, R21 ; Reduce the value so it is below 230
NotGreater: ;; Label

DEC R22 ;; R22--
CP R22, R0 ;; Check if R22 !=0

BRNE PushList ; If R22 !=0, continue loop


//////////////////////////////////////  END Generate List











////////////////////////////////////// Determine divisible by 3 and 5. And add values to registers

LDI R16, 20 ; State how many numbers want to be iterated


;;;; Now go through the list of numbers and add them if divisible by 3 or 5. And save values to R 20/21 or R 23/24

;; Clear the registers to hold the sum of numbers
MOV R20, R0 ;; Clear R20
MOV R21, R0 ;; Clear R21
MOV R23, R0 ;; Clear R23
MOV R24, R0 ;; Clear R24

FindDivBy3and5:
POP R17 ; Take number off of the list
MOV R22, R17 ; R22 holds the original number. R17 will be subject to the logic of obtaining if divisible


;; As each number must be between 30 and 250, we can minus 30 (as it is a factor of 3 and 5) over and over again until less than 30.

LDI R18, 30 ; Load 30 so to compare against
ReduceByX ;; Macro to reduce until less than or equal 30

;; This number must now be less than 30. As 15 is a factor of both 3 and 5, we can reduce by 15, until less than.


LDI R18, 15 ; Load 15 so to compare against
ReduceByX ;; Macro to reduce until less than or equal 15

// Now the number must be less than 15. 


// Now we can subtract by 3 until it is less than 3. If it is 0, it is divisible.
MOV R25, R17 ; Need a copy of the reduced number for both 3 and 5.

LDI R18, 3 ; Load 3 so to compare against
ReduceByX ;; Macro to reduce until less than or equal 3


CP R0,R17 ; If R17==0, then it is divisible by 3
BRNE NotDivisibleBy3 ; Skip adding the original number if not divisible
ADD R20, R22 ; Add the original number on the stack to R20:R21 as per assignment requirment
ADC R21, R0 ; Carry over bit to R21.
NotDivisibleBy3: ; Goes here if not divisible by 3




// Now we can subtract by 5 until it is less than 5. If it is 0, it is divisible.

MOV R17, R25 ;; Set R17 back before 3 touched it

LDI R18, 5 ; Load 5 so to compare against
ReduceByX ;; Macro to reduce until less than or equal 5

CP R0,R17 ; If R25==0, then it is divisible by 5
BRNE NotDivisibleBy5 ; Skip adding the original number if not divisible
ADD R23, R22 ; Add the original number on the stack to R23:R24 as per assignment requirment
ADC R24, R0 ; Carry over bit to R21.
NotDivisibleBy5: ; Goes here if not divisible by 5

DEC R16 ; This decrements the counter of going through the stack
CP R16, R0 ; Check if fully went through stack
BRNE FindDivBy3and5 ; If R16 == 0



//////////////////////////////////////  END Determine divisible by 3 and 5. And add values to registers


BreakPoint



